﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace YouTubeStormer
{
    class Configuration
    {
        public static string VideoInfoSplitter = "~`~";

        public static string[] GetAccountUsernames()
        {
            var accounts = StringCollectionToArray(Properties.Settings.Default.Accounts);
            for (int i = 0; i < accounts.Length; i++)
            {
                accounts[i] = accounts[i].Split(':')[0];
            }
            return accounts;
        }

        public static string[] StringCollectionToArray(StringCollection collection, bool randomize = false)
        {
            Random ran = new Random();
            var array = new string[collection.Count];
            collection.CopyTo(array, 0);
            if (randomize)
                return array.OrderBy(x => ran.Next()).ToArray();
            else
                return array;
        }

        public class AccountInfo
        {
            public string Username { get; set; }
            public string Password { get; set; }
            public Communications.ProxyInfo Proxy { get; set; }
        }

        public class CommentInfo
        {
            public string ID { get; set; }
            public string Author { get; set; }
            public string Score { get; set; }
            public string Text { get; set; }
            public string Tag { get; set; }
            public bool Spammed { get; set; }
            public bool HighestRated { get; set; }
            public bool Pending { get; set; }

            public CommentInfo()
            {
                HighestRated = false;
                Spammed = false;
                Pending = false;
            }
        }

        public class VideoInfo
        {
            public string VideoID { get; set; }
            public string Tag { get; set; }
            public string Description { get; set; }
        }

        public static VideoInfo[] ParseVideos()
        {
            var videos = Configuration.StringCollectionToArray(Properties.Settings.Default.Videos);
            var videoInfoArray = new VideoInfo[videos.Length];
            for (int i = 0; i < videoInfoArray.Length; i++)
            {
                var videoInfoParts = Regex.Split(videos[i], VideoInfoSplitter);
                var newVideoInfo = new VideoInfo { VideoID = videoInfoParts[0] };
                if (videoInfoParts.Length > 0) newVideoInfo.Tag = videoInfoParts[1];
                if (videoInfoParts.Length > 1) newVideoInfo.Description = videoInfoParts[2];

                videoInfoArray[i] = newVideoInfo;
            }
            return videoInfoArray;
        }

        public static AccountInfo ParseAccount(string accountLine)
        {
            try
            {
                var accountParts = accountLine.Split(':');
                return new AccountInfo { Username = accountParts[0], Password = accountParts[1], Proxy = new Communications.ProxyInfo { IP = accountParts[2], Port = accountParts[3], Username = accountParts[4], Password = accountParts[5] } };
            }
            catch { return null; }
        }

        public static CommentInfo SearchForComment(CommentInfo[] collection)
        {
            foreach (CommentInfo comment in collection)
            {
                foreach (string username in GetAccountUsernames())
                {
                    if (comment.Author.ToLower() == username.ToLower())
                        return comment;
                }
            }
            return null;
        }

        public static CommentInfo FindComment(Communications communications, string videoID, bool deepSearch = false)
        {
            CommentInfo[] collection = ParseComments(communications.PerformGet(Urls.YoutubeWatchUrl + videoID));
            var comment = SearchForComment(collection);
            if (deepSearch && comment == null)
                return SearchForComment(ParseComments(communications.PerformGet(Urls.YoutubeCommentServerUrl + videoID)));
            else
                return comment;
        }

        public static CommentInfo[] ParseComments(string document)
        {
            string[] commentBlocks = Regex.Split(document, "<li ");
            List<CommentInfo> commentDetails = new List<CommentInfo>();
            foreach (string commentBlock in commentBlocks)
            {
                var comment = ParseComment(commentBlock);
                if (comment != null) commentDetails.Add(comment);
            }
            return commentDetails.ToArray();
        }

        public static CommentInfo ParseComment(string block)
        {
            var comment = new CommentInfo();
            string[] commentBlockLines = block.Split('\n');
            for (int i = 0; i < commentBlockLines.Length; i++)
            {
                if (commentBlockLines[i].Contains("comment-text")) comment.Text = commentBlockLines[i + 1].Trim();
                if (commentBlockLines[i].Contains("data-id")) comment.ID = commentBlockLines[i].Split('=')[1].Replace("\"", "");
                if (commentBlockLines[i].Contains("data-author")) comment.Author = commentBlockLines[i].Split('=')[1].Replace("\"", "");
                if (commentBlockLines[i].Contains("data-score")) comment.Score = commentBlockLines[i].Split('=')[1].Replace("\"", "");
                if (commentBlockLines[i].Contains("data-flagged")) comment.Spammed = bool.Parse(commentBlockLines[i].Split('=')[1].Replace("\"", ""));
                if (commentBlockLines[i].Contains("data-tag"))
                {
                    comment.Tag = commentBlockLines[i].Split('=')[1].Replace("\"", "");
                    comment.HighestRated = (comment.Tag == "R");
                }
                if (commentBlockLines[i].Contains("data-pending"))
                {
                    var commentPending = commentBlockLines[i].Split('=')[1].Replace("\"", "");
                    comment.Pending = (commentPending == "2");
                }

            }
            if (comment.ID != null)
                return comment;
            else
                return null;
        }

        public static int GetPossibleCommentCombos()
        {
            int combos = 1;
            var partLists = StringCollectionToArray(Properties.Settings.Default.CommentParts);
            foreach (string partList in partLists)
            {
                var enties = Regex.Split(partList, "\n");
                combos = combos * enties.Length;
            }
            return combos;
        }

        public static string GenerateComment(string tag)
        {
            try
            {
                var random = new Random();
                for (int i = 0; i < random.Next(40, 100); i++)
                {
                    random.Next(0, random.Next(0, 100));
                }

                string comment = "";
                var partLists = StringCollectionToArray(Properties.Settings.Default.CommentParts);

                foreach (string partList in partLists)
                {
                    var enties = Regex.Split(partList, "\n");
                    comment += enties[random.Next(0, enties.Length)];
                }

                var links = Properties.Settings.Default.Links;
                return comment.Replace("{LINK}", links[random.Next(0, links.Count)]).Replace("{TAG}", tag);
            }
            catch
            {
                return "";
            }
        }

        public static void RemoveVideo(string videoID)
        {
            foreach (string videoInfoLine in StringCollectionToArray(Properties.Settings.Default.Videos))
            {
                if (Regex.Split(videoInfoLine, VideoInfoSplitter)[0] == videoID)
                {
                    Properties.Settings.Default.Videos.Remove(videoInfoLine);
                    Properties.Settings.Default.Save();
                    return;
                }
            }
        }
    }
}
